home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 8 / Night Owl CD-ROM (NOPV8) (Night Owl Publisher) (1993).ISO / 017a / binutils.arj / RANLIB.C < prev    next >
C/C++ Source or Header  |  1991-03-27  |  5KB  |  234 lines

  1. /* Dummy ranlib program for GNU.
  2.    All it does is `ar rs LIBRARY' for each library specified.
  3.  
  4.    Copyright (C) 1989 Free Software Foundation, Inc.
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 1, or (at your option)
  9.    any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <ar.h>
  21. #include <sys/types.h>
  22. #include <sys/file.h>
  23. #include <stdio.h>
  24. #include <fcntl.h>
  25. #include "getopt.h"
  26. #include "signame.h"
  27.  
  28. #ifndef L_SET
  29. #define L_SET 0
  30. #define L_INCR 1
  31. #endif
  32.  
  33. #ifndef X_OK
  34. #define X_OK 1
  35. #endif
  36.  
  37. #ifdef USG
  38. #define bzero(s, n) (memset ((s), 0, (n)))
  39. #define gettimeofday(TV,TZ) (time (TV))
  40. #define seconds(TV) TV
  41. long time();
  42. #else
  43. #define seconds(TV) TV.tv_sec
  44. #include <sys/time.h>
  45. #endif
  46.  
  47. #ifdef USG
  48. #define    vfork    fork
  49. #endif
  50.  
  51. void touch_symdefs ();
  52.  
  53. /* The makefile generates a -D switch to define AR_PROG
  54.    as the location of the GNU AR program.  */
  55.  
  56. char *prog = AR_PROG;
  57. char *prog_pref = "/usr/local/gnubin/ar";
  58.  
  59. int
  60. main (argc, argv)
  61.      int argc;
  62.      char **argv;
  63. {
  64.   static int touch = 0, verbose = 0;
  65.   int lose = 0;
  66.   static char short_opts[] = "tv";
  67.   static struct option long_opts[] =
  68.     {
  69.       { "touch", 0, &touch, 0 },
  70.       { "verbose", 0, &verbose, 0 },
  71.       { 0, 0, 0, 0 }
  72.     };
  73.   extern int optind;
  74.   register int c;
  75.   char *args;
  76.   int junk;
  77.   char *ar_program;
  78.  
  79.   while ((c = getopt_long (argc, argv, short_opts, long_opts, &junk)) != EOF)
  80.     switch (c)
  81.       {
  82.       case 't':
  83.     touch = 1;
  84.     break;
  85.  
  86.       case 'v':
  87.     verbose = 1;
  88.     break;
  89.  
  90.       default:
  91.     lose = 1;
  92.     break;
  93.       }
  94.  
  95.   if (lose)
  96.     {
  97.       fprintf (stderr, "Usage: %s [-tv] [+touch] [+verbose] file...\n",
  98.            argv[0]);
  99.       exit (1);
  100.     }
  101.  
  102.   if (access (prog_pref, X_OK) == 0)
  103.     ar_program = prog_pref;
  104.   else
  105.     ar_program = prog;
  106.  
  107.   args = verbose ? "rsv" : "rs";
  108.  
  109.   if (touch)
  110.     touch_symdefs (argc - optind, argv + optind);
  111.   else
  112.     {
  113.       register int i;
  114.       for (i = optind; i < argc; ++i)
  115.     {
  116.       int pid;
  117.  
  118.       if (verbose)
  119.         printf ("%s %s %s\n", ar_program, args, argv[i]);
  120.  
  121.       fflush (stdout);
  122.       fflush (stderr);
  123.  
  124.       pid = vfork ();
  125.       if (pid < 0)
  126.         {
  127.           fprintf (stderr, "ranlib: can not ");
  128.           perror ("vfork");
  129.         }
  130.       else if (pid == 0)
  131.         {
  132.           /* Child side.  */
  133.           execl (ar_program, ar_program, args, argv[i], 0);
  134.           fprintf (stderr, "ranlib: can not run ");
  135.           perror (ar_program);
  136.           exit (1);
  137.         }
  138.       else
  139.         {
  140.           /* Parent side.  */
  141.           int status;
  142.           if (wait (&status) != pid)
  143.         {
  144.           fprintf (stderr, "ranlib: interrupted during ");
  145.           perror ("wait");
  146.         }
  147.           if ((status & 0x7f) != 0)
  148.         {
  149.           psignal (status & 0x7f, ar_program);
  150.           exit (1);
  151.         }
  152.           else if (((status & 0xff00) >> 8) != 0)
  153.         exit ((status & 0xff00) >> 8);
  154.         }
  155.     }
  156.     }
  157.  
  158.   exit (0);
  159. }
  160.  
  161. /* Take a list of archive files to "touch".  This subroutine will then
  162.    find the first symdef member in them and update the date to the
  163.    current one.  */
  164.  
  165. void
  166. touch_symdefs (largc, largv)
  167.      int largc;
  168.      char **largv;
  169. {
  170. #ifdef USG
  171.   long tv;
  172. #else
  173.   struct timeval tv;
  174.   struct timezone tz;
  175. #endif
  176.  
  177.   struct ar_hdr archive_header;
  178.   int i, rr;
  179.  
  180.   gettimeofday (&tv, &tz);
  181.  
  182.   while (largc--)
  183.     {
  184.       int fd = open (*largv, O_RDWR);
  185.  
  186.       if (fd < 0)
  187.     {
  188.       fprintf (stderr, "ranlib: can not open `%s' for ", *largv);
  189.       perror ("read/write");
  190.       largv++;
  191.       continue;
  192.     }
  193.  
  194.       lseek (fd, SARMAG, L_SET);
  195.  
  196.       rr = read (fd, &archive_header, sizeof (archive_header));
  197.  
  198.       /* In the general case this loop would be sped up by buffering,
  199.          but in almost all cases the symdef will be the first member, so
  200.      I'm not going to bother.  */
  201.       
  202.       while (rr == sizeof (archive_header))
  203.     {
  204.       if (!strncmp ("__.SYMDEF", archive_header.ar_name,
  205.             sizeof ("__.SYMDEF") - 1))
  206.         {
  207.           bzero ((char *) archive_header.ar_date,
  208.              sizeof (archive_header.ar_date));
  209.  
  210.           sprintf (archive_header.ar_date, "%d", seconds (tv));
  211.           
  212.           for (i = 0; i < sizeof archive_header.ar_date; i++)
  213.         if (archive_header.ar_date[i] == '\0')
  214.           archive_header.ar_date[i] = ' ';
  215.  
  216.           lseek (fd, - rr, L_INCR);
  217.           write (fd, &archive_header, sizeof (archive_header));
  218.           close (fd);
  219.           break;
  220.         }
  221.  
  222.       lseek (fd, atoi (archive_header.ar_size), L_INCR);
  223.       rr = read (fd, &archive_header, sizeof (archive_header));
  224.     }
  225.  
  226.       if (rr != sizeof (archive_header))
  227.     /* We reached the end of the file.  */
  228.     fprintf (stderr, "ranlib: can not find `__.SYMDEF' member in `%s'\n",
  229.          *largv);
  230.  
  231.       largv++;
  232.     }
  233. }
  234.